﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Messaging;

namespace ProjectSpam
{
    public partial class Recover_Tree : Form
    {
        BackUpInfo bInfo;
        string path;
        Packer packer;

        const string sendQueue = ".\\private$\\projectSpamQueue";

        public Recover_Tree(object info)
        {
            InitializeComponent();
            bInfo = (BackUpInfo)info;
            this.path = bInfo.Folder;
            this.label_name.Text = bInfo.Name;

            packer = new Packer();

            //display tree
            treeView.PathSeparator = @"\\";
            treeView.Nodes.Clear();
            PopulateTreeView(treeView, bInfo.Files, '\\');
            //DisplayBackup();

        }

        private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
        {

        }

        private void recover(string path, string name, string compressed, List<string> files)
        {
            List<string> recoverInf = new List<string>();
            recoverInf.Add(name);
            recoverInf.Add(compressed);
            recoverInf.Add(path);
            recoverInf.AddRange(files);

            SendMessageToQueue(recoverInf);
        }


        private void button_recover_Click(object sender, EventArgs e)
        {
            this.recover(bInfo.Folder, bInfo.Name,""+ bInfo.Compressed, this.CheckedNames(treeView.Nodes, "", 0));

            packer.unPack(bInfo.Folder, bInfo.Name, bInfo.Compressed, this.CheckedNames(treeView.Nodes,"",0));
            MessageBox.Show("Recovery in Progress!");
        }

        private void button_recoverAs_Click(object sender, EventArgs e)
        {
            string newPath;

            DialogResult result = folderBrowserDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                newPath = folderBrowserDialog1.SelectedPath;
                this.recover(newPath, bInfo.Name, "" + bInfo.Compressed, this.CheckedNames(treeView.Nodes, "", 0));
            }
        }

        private static void SendMessageToQueue(List<string> files)
        {
            // check if queue exists, if not create it

            MessageQueue msMq = null;
            try
            {
                if (!MessageQueue.Exists(sendQueue))
                {
                    msMq = MessageQueue.Create(sendQueue);
                }
                else
                {
                    msMq = new MessageQueue(sendQueue);
                }
            }
            catch (MessageQueueException e)
            {

            }

            try
            {
                msMq.Send("Sending data to MSMQ at " + DateTime.Now.ToString());

                System.Messaging.Message newMessage = new System.Messaging.Message(files);
                msMq.Send(newMessage);
                // msMq.Send(files);
            }
            catch (MessageQueueException ee)
            {
                Console.Write(ee.ToString());
            }
            catch (Exception eee)
            {
                Console.Write(eee.ToString());
            }
            finally
            {
                msMq.Close();
                MessageBox.Show("Recovery initiated");
            }


        }


        List<String> CheckedNames(System.Windows.Forms.TreeNodeCollection theNodes, string parent, int depth)
        {
            List<String> aResult = new List<String>();

            if (theNodes != null)
            {
                foreach (System.Windows.Forms.TreeNode aNode in theNodes)
                {
                    string path;
                    if (depth >= 0)
                    {

                        if (aNode.Checked)
                        {
                            if (aNode.Nodes.Count == 0)
                            {
                                aResult.Add(parent + aNode.Text);
                            }
                        }

                        path = parent + aNode.Text + "\\";
                    }
                    else
                    {
                        if (aNode.Checked)
                        {

                            if (aNode.Nodes.Count == 0)
                            {
                                aResult.Add(aNode.Text);
                            }
                        }

                        path = "";
                    }



                    aResult.AddRange(CheckedNames(aNode.Nodes, path, ++depth));
                }
            }

            return aResult;
        }


        private static TreeNode CreateDirectoryNode(System.IO.DirectoryInfo directoryInfo)
        {
            var directoryNode = new TreeNode(directoryInfo.Name);


            foreach (var directory in directoryInfo.GetDirectories())
            {
                try
                {
                    directoryNode.Nodes.Add(CreateDirectoryNode(directory));
                }
                catch (UnauthorizedAccessException e)
                {
                }
            }
            
            
            foreach (var file in directoryInfo.GetFiles())
                directoryNode.Nodes.Add(new TreeNode(file.Name));


            return directoryNode;
        }





        private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
        {
            foreach (TreeNode node in treeNode.Nodes)
            {
                node.Checked = nodeChecked;
                if (node.Nodes.Count > 0)
                {

                    this.CheckAllChildNodes(node, nodeChecked);
                }
            }
        }

        private void treeView_AfterCheck(object sender, TreeViewEventArgs e)
        {

            if (e.Action != TreeViewAction.Unknown)
            {
                if (e.Node.Nodes.Count > 0)
                {

                    this.CheckAllChildNodes(e.Node, e.Node.Checked);
                }
            }
        }

        private void button_cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private static void PopulateTreeView(TreeView treeView, IEnumerable<string> paths, char pathSeparator)
        {
            TreeNode lastNode = null;
            string subPathAgg;
            foreach (string path in paths)
            {
                subPathAgg = string.Empty;
                
                foreach (string subPath in path.Split(pathSeparator))
                {
                    subPathAgg += subPath + pathSeparator;
                    TreeNode[] nodes = treeView.Nodes.Find(subPathAgg, true);
                    if (nodes.Length == 0)
                        if (lastNode == null)
                            lastNode = treeView.Nodes.Add(subPathAgg, subPath);
                        else
                            lastNode = lastNode.Nodes.Add(subPathAgg, subPath);
                    else
                        lastNode = nodes[0];
                }
            }
        }
    }
}
